/**
 * JungoMobileWeb
 * LoginController.java
 * 
 * Copyright 2013 Teachizen
 * Written by cloudstick
 *	2013. 7. 26. first written.
 *
 * note:
 */
package com.jungo.web.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.jungo.web.bean.User;
import com.jungo.web.dao.LoginDao;

/**
 * @author cloudstick
 *
 */
@Controller
@Slf4j
public class LoginController {

	enum AuthResult {
		SUCCESS(0),
		INVALID_USER(-1),
		INVALID_PASSWORD(-2),
		EXIST_USER(-3),
		EXIST_DEVICE_ID(-4);
		
		int value;
		
		private AuthResult(int value) {
			this.value = value;
		}
		
		public int getValue() {
			return value;
		}
	}
	
	@Autowired
	private LoginDao loginDao;
	
	/**
	 * 로그인 페이지 표시
	 * @return login.jsp
	 */
	@RequestMapping(value="/login.do", method=RequestMethod.GET)
	public String login() {
		return "auth/login";
	}
	
	/**
	 * 계정 정보를 받아 가입 사용자인지 확인한다.
	 * @param submitUser view에서 값이 바인딩된 User 객체
	 * @param session 회원 정보를 저장하기 위한 세션 객체
	 * @param model 결과 코드를 view에 전달하기 위한 ModelMap
	 * @return login 페이지 또는 products 페이지
	 */
	@RequestMapping(value="/login.do", method=RequestMethod.POST)
	public String login(@ModelAttribute User submitUser,
						@RequestParam("from") String from,
						HttpSession session, 
						ModelMap model) {
		
		User user = loginDao.getUser(nonNull(submitUser).getUserid().trim());
		log.debug("Login user info[{}]", user);
		
		if ( user == null ) {
			model.addAttribute("code", AuthResult.INVALID_USER.getValue());
			return "/auth/login";
		}
		
		if ( !user.getPassword().equals(submitUser.getPassword().trim()) ) {
			model.addAttribute("code", AuthResult.INVALID_PASSWORD.getValue());
			return "/auth/login";
		}

		//로그인이 성공하면 registrationId를 업데이트 한다.
		if ( user.getRid() != null && !"".equals(user.getRid()) ) {
			loginDao.updateRegistrationId(user);
		}
		
		log.debug("from value[{}]", from);
		//세션 정보 저장
		session.setAttribute("user", user);
		log.debug("login.do user[{}]", user);
		if ( "myFavorites".equals(from) ) {
			return "redirect:/myFavorites.do";
		} else if ( "myProducts".equals(from) ) {
			return "redirect:/myProducts.do";
		} 
		return "redirect:/products.do";
	}
	
	/**
	 * 세션 객체를 무효화시킨다.
	 * @param session 사용자 정보가 포함된 세션 객체
	 * @return index.jsp
	 */
	@RequestMapping("/logout.do")
	public String logout(HttpSession session) {
		session.invalidate();
		log.debug("Session invalidated.");
		return "redirect:/index.do";
	}
	
	/**
	 * 회원 가입 페이지를 표시한다.
	 * @return account.jsp
	 */
	@RequestMapping(value="/account.do", method=RequestMethod.GET) 
	public String account(HttpSession session) {
		return "auth/account";
	}
	
	/**
	 * ajax 사용자 정보를 저장한다.
	 * @param request 사용자 정보가 포함된 요청 객체
	 * @return 문자열 형식의 json 메시지
	 */
	
	/**
	 * 새로운 사용자 정보를 등록한다.
	 * @param submitUser form에서 전달하여 바인딩된 User 객체
	 * @param session 회원 정보를 저장하기 위한 세션 객체
	 * @param model 결과 코드를 view에 전달하기 위한 ModelMap
	 * @return account 페이지 또는 products 페이지
	 */
	@RequestMapping(value="/account.do", method=RequestMethod.POST)
	public String registerAccount(@ModelAttribute User submitUser, HttpSession session, ModelMap model) {
		
		if ( loginDao.existUser(submitUser.getUserid()) ) {
			model.addAttribute("code", AuthResult.EXIST_USER.getValue());
			return "auth/account";
		}
		
		if ( loginDao.existDeviceId(submitUser.getDevice_id()) ) {
			model.addAttribute("code", AuthResult.EXIST_DEVICE_ID.getValue());
			return "auth/account";
		}
		
		try {
			loginDao.setUser(submitUser);
		} catch(Exception e) {
			log.error("Exception occured.", e);
		}
		
		//사용자 정보를 세션 객체에 저장
		session.setAttribute("user", submitUser);
		
		log.info("Account user info. user[{}]", submitUser);
		return "redirect:/products.do";
	}
	
	static <T> T nonNull(T argument) {
		if ( argument == null ) {
			throw new IllegalArgumentException("argument cannot be null.");
		}
		return argument;
	}
}
